/*
 * Treebank.cpp
 *
 *  Created on: Dec 18, 2014
 *      Author: Phong
 */

#include "Treebank.h"
#include <vector>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include "Utils.h"
#include "Depstruct.h"

using namespace std;

Treebank::~Treebank() {
    for (int i = 0; i < this->size(); i++)
        Deptree::free(storage[i]);
}

Treebank* Treebank::share() {
    refCount++;
    return this;
}

void Treebank::free(Treebank *tb) {
    tb->refCount--;
    if (tb->refCount == 0) delete tb;
}

Treebank* Treebank::load(string fname, Dictionary* vocaDic, Dictionary* posDic, Dictionary* deprelDic) {
    cout << "load " << fname << endl;
    Treebank* tb = new Treebank();
	fstream reader(fname, ios::in);
	vector<string> rows;
	string line;

	while (getline(reader, line)) {
		vector<string> comps = Utils::splitStringWoRegex(line, "\t");
		if (comps.size() == 1) {
            Depstruct* ds = Depstruct::create(rows, vocaDic, posDic, deprelDic);
			tb->storage.push_back(ds->toDepTree());
            Depstruct::free(ds);
            rows.clear();

			if (tb->size() % 1000 == 0) {
                cout << tb->size() << "\r" << flush;
			}

		}
		else {
			rows.push_back(line);
		}
	}
    cout << tb->size() << " trees" << endl;
	reader.close();
	return tb;
}

void Treebank::shuffle() {
	for (int i = (int)storage.size() - 1; i > 0; i--)
	{
		int index = rand() % storage.size();
        Deptree* temp = storage[index];
        storage[index] = storage[i];
        storage[i] = temp;
	}
}

vector<Depstruct*> Treebank::getDsBank() {
    vector<Depstruct*> ret(size());
    for (int i = 0; i < size(); i++)
        ret[i] = storage[i]->ds;
    return ret;
}
